package com.swak.sql.parsing.engine;

import com.swak.parser.exception.SqlParseException;
import com.swak.parser.lexer.LexerEngine;
import com.swak.parser.lexer.token.DefaultKeyword;
import com.swak.parser.lexer.token.Token;
import com.swak.sql.parsing.SqlParser;
import com.swak.sql.parsing.context.Statement;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Setter
@Getter
@Accessors(chain = true)
public abstract class AbstractSqlParser implements SqlParser {

	protected final LexerEngine lexer;

	public AbstractSqlParser(LexerEngine lexer) {
		this.lexer = lexer;
	}

	@Override
	public Statement parse() {
		lexer.nextToken();
		Token token = lexer.getCurrentToken();
		if (this.isSelect(token)) {
			return this.parseSelect();
		} else if (this.isInsert(token)) {
			return this.parseInsert();
		} else if (this.isUpdate(token)) {
			return this.parseUpdate();
		} else if (this.isDelete(token)) {
			return this.parseDelete();
		}
		throw new SqlParseException(token.getType());
	}

	protected boolean isSelect(Token token) {
		return token.getType() == DefaultKeyword.SELECT;
	}

	protected boolean isInsert(Token token) {
		return token.getType() == DefaultKeyword.INSERT;
	}

	protected boolean isUpdate(Token token) {
		return token.getType() == DefaultKeyword.UPDATE;
	}

	protected boolean isDelete(Token token) {
		return token.getType() == DefaultKeyword.DELETE;
	}

	protected abstract Statement parseSelect();

	protected abstract Statement parseInsert();

	protected abstract Statement parseUpdate();

	protected abstract Statement parseDelete();
}
